﻿import * as sfs from "fs";
import * as q from 'q';
import { join, dirname, basename } from "path";
import * as crypto from 'crypto';
import { create } from "domain";
import { createHash } from "crypto";
import { AppContext } from "../appContext";

export class VSCode {
    truncate(path: string, len: number) {
        path = AppContext.map_vscode_path(path);
        return q.promise((resolve, reject) => {
            sfs.truncate(path, len, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve();
            });
        });
    }
    writeFile(path: string, data: string, options: any) {
        path = AppContext.map_vscode_path(path);
        return q.promise((resolve, reject) => {
            sfs.writeFile(path, data, options, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve();
            });
        });
    }
    readDirsInDir(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.promise((resolve, reject) => {
            sfs.readdir(path, (err, files) => {
                if (err) {
                    reject(err);
                    return;
                }
                var directoies = files.map(file => {
                    var fileName = join(path, file);
                    var stats = sfs.statSync(fileName);
                    this.wrap(stats, path, file);
                    return stats;
                }).filter(file => file.isDirectory());
                resolve(directoies);
            });
        });
    }
    readdir(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.promise((resolve, reject) => {
            sfs.readdir(path, (err, files) => {
                if (err) {
                    reject(err);
                    return;
                }
                var directoies = files.map(file => {
                    var fileName = join(path, file);
                    var stats = sfs.statSync(fileName);
                    this.wrap(stats, path, file);
                    return stats;
                });
                resolve(directoies);
            });
        });
    }
    etag(size: number, mtime: Date) {
        return crypto.createHash("sha1")
            .update(size.toLocaleString() + mtime.getTime().toLocaleString())
            .digest("hex");
    }
    wrap(stats: sfs.Stats, path: string, file: string) {
        stats["atimestamp"] = stats.atime.getTime();
        stats["birthtimestamp"] = stats.birthtime.getTime();
        stats["mtimestamp"] = stats.mtime.getTime();
        stats["directory"] = stats.isDirectory();
        stats["blockDevice"] = stats.isBlockDevice();
        stats["characterDevice"] = stats.isCharacterDevice();
        stats["fifo"] = stats.isFIFO();
        stats["file"] = stats.isFile();
        stats["socket"] = stats.isSocket();
        stats["symbolicLink"] = stats.isSymbolicLink();
        stats["etag"] = this.etag(stats.size, stats.mtime);
        stats["fullName"] = join(path, file);
        stats["name"] = file;
    }
    stat(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.Promise((resolve, reject) => {
            sfs.stat(path, (err, stats) => {
                if (err) {
                    reject(err);
                    return;
                }
                this.wrap(stats, path, basename(path));
                resolve(stats);
            });
        });
    }
    readFile(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.Promise((resolve, reject) => {
            sfs.readFile(path, "utf8", (err, data) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve(data);
            });
        });
    }
    exists(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.Promise((resolve, reject) => {
            sfs.exists(path, (data) => {
                resolve(data);
            });
        });
    }
    chmod(path: string, mode: number) {
        path = AppContext.map_vscode_path(path);
        return q.Promise((resolve, reject) => {
            sfs.chmod(path, mode, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve();
            });
        });
    }
    mkdir(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.Promise((resolve, reject) => {
            sfs.mkdir(path, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve({
                    success: true
                });
            });
        });
    }
    realpath(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.Promise((resolve, reject) => {
            sfs.realpath(path, (err, rpath) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve(rpath);
            });
        });
    }
    access(path: string) {
        path = AppContext.map_vscode_path(path);
        return q.Promise((resolve, reject) => {
            sfs.access(path, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve();
            });
        });
    }
}